package leaveSystem.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import leaveSystem.bizlogic.LeaveManager;
import leaveSystem.model.ApplyLeaveFormBean;
import leaveSystem.model.Employee;
import leaveSystem.model.Leave;
import leaveSystem.model.PublicHolidays;
import leaveSystem.utility.DateUtility;

/**
 * Servlet implementation class ApplyLeaveServlet
 */
@WebServlet("/ApplyLeaveServlet")
public class ApplyLeaveServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
   
    public ApplyLeaveServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		LeaveManager leaveManager = new LeaveManager();
		RequestDispatcher rs=null;
		DateUtility dutil = new DateUtility();
		
		// get current login user from session
		HttpSession session = request.getSession();
		Employee resultEmp = (Employee) session.getAttribute("currentSessionUser");
System.out.println(">>>>doGet<<<<<<");		
		Leave leave = new Leave();
		leave.setLeaveId(Integer.parseInt(request.getParameter("leaveid")));
//		leave.setLeaveId(4);
		
		List<Leave> rst = leaveManager.getStaffsLeave(leave);
		request.setAttribute("leave", rst.get(0));
		session.setAttribute("leaveid", leave.getLeaveId());
		rs = request.getRequestDispatcher("ApplyLeaveForm.jsp");
		rs.forward(request, response);
		
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			applyLeaveProcess(request, response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@SuppressWarnings("deprecation")
	protected void applyLeaveProcess(HttpServletRequest request, HttpServletResponse response) throws IOException,Exception {
		LeaveManager leaveManager = new LeaveManager();
		RequestDispatcher rs=null;
		DateUtility dutil = new DateUtility();
		
		// get current login user from session
		HttpSession session = request.getSession();
		Employee resultEmp = (Employee) session.getAttribute("currentSessionUser");
		       			
		//check conditions		
		int leaveType = Integer.parseInt(request.getParameter("leavetype"));
		Integer lid = (Integer) session.getAttribute("leaveid");
	
			//calculate no of days
			Date fromDate = dutil.ConvertStringToDate(request.getParameter("fromDate"));
			Date toDate = dutil.ConvertStringToDate(request.getParameter("toDate"));

			//start date validation
			if(fromDate.before(dutil.getDate())){
				System.out.println("From Date should start today or after today");
				request.setAttribute("errorMessage", "From Date should start today or after today");
				rs = request.getRequestDispatcher("ApplyLeaveForm.jsp");
				rs.forward(request, response);
				
			}else if(fromDate.after(toDate)){
				System.out.println("From Date should be before ToDate");
				request.setAttribute("errorMessage", "From Date should be before ToDate");
				rs = request.getRequestDispatcher("ApplyLeaveForm.jsp");
				rs.forward(request, response);
			}
			else{
				request.setAttribute("errorMessage", null);
				long days = toDate.getTime()-fromDate.getTime();
				int noOfDays= (int)days / (24 * 60 * 60 * 1000);
		System.out.println(noOfDays);
				int leavePeriod = noOfDays+1;
			
				//find by leave type
				Leave leave = new Leave();
				leave.setEmployeeId(resultEmp.getEmployeeId());
				leave.setLeaveTypeId(leaveType);
				int takenLeave = leaveManager.countNoOfLeave(leave);
		System.out.println("Taken leaves "+takenLeave);
		
				if(leaveType==1){//annual leave
					if(leavePeriod<=14){
						//exclude the weekends
						if(leavePeriod == 6){
							leavePeriod =leavePeriod-1;
							System.out.println("==6");
						}
						else if( leavePeriod >=7 && leavePeriod <=12){
							leavePeriod =leavePeriod-2;
							System.out.println("==7");
						}
						else if(leavePeriod == 13){
							leavePeriod =leavePeriod-3;
							System.out.println("==13");
						}
						else if(leavePeriod == 14){
							System.out.println("==14");
							leavePeriod =leavePeriod-4;
						}
				System.out.println("leave Period "+leavePeriod);		
						//exclude public holidays
				try{
					String frm = request.getParameter("fromDate");
					String[] rst1 = frm.split("-");
					String to = request.getParameter("toDate");
					String[] rst2 = to.split("-");
					String fd = rst1[2]+"-"+rst1[1]+"-"+rst1[0];
					String td = rst2[2]+"-"+rst2[1]+"-"+rst2[0];
					System.out.println(fd + " "+td);
					String fmt = "yyyy-MM-dd";
					DateFormat df = new SimpleDateFormat(fmt);
					
					Date fdate = df.parse(fd);
					Date tdate = df.parse(td);
					System.out.println(fdate + " "+tdate);
					List<PublicHolidays> rst = leaveManager.getHolidaysByDates(fd, td);	
					if(rst!=null)
					leavePeriod = leavePeriod - rst.size();
					System.out.println(rst.size()+" leave Period excluded public holiday "+leavePeriod);
				}catch(Exception e){
					e.printStackTrace();
				}
				
				
				
						if(resultEmp.getEmployeeRank().equals("professional")){
							if(takenLeave<18){
								//give leave
								//check public holiday
								//prepare Leave Object to save
								Leave saveLeave = prepareLeaveObject(request,response,resultEmp,leavePeriod,leaveType);
								//save to database
								if(lid==null)
									leaveManager.createLeave(saveLeave);
								else{
									saveLeave.setLeaveId(lid);
									saveLeave.setStatus("Updated");
									leaveManager.updateLeave(saveLeave);
								}
								request.setAttribute("errorMessage", "Leave Application Process is successful!");
							}
							else{
								System.out.println("Your annual leave is not left");
								request.setAttribute("errorMessage", "Your annual leave is not left");
							}
						}
						else{
							if(takenLeave<14){
								//give leave	
								//prepare Leave Object to save
								Leave saveLeave = prepareLeaveObject(request,response,resultEmp,leavePeriod,leaveType);
								//save to database
								if(lid==null)
									leaveManager.createLeave(saveLeave);
								else{
									saveLeave.setLeaveId(lid);
									saveLeave.setStatus("Updated");
									leaveManager.updateLeave(saveLeave);
								}
								request.setAttribute("errorMessage", "Leave Application Process is successful!");
							}
							else{
								System.out.println("Your annual leave is not left");
								request.setAttribute("errorMessage", "Your annual leave is not left");
							}
						}
					}//leavePeriod is >14
					else{
						System.out.println("You took greater 14");
						request.setAttribute("errorMessage", "You took greater 14 and No more annual leave is left");
					}
					
					rs = request.getRequestDispatcher("ApplyLeaveForm.jsp");
					rs.forward(request, response);
				}
				//medical leave
				else if(leaveType==2){
					if(takenLeave <60){
						//give leave
						System.out.println("You can take medical leave");
						//prepare Leave Object to save
						Leave saveLeave = prepareLeaveObject(request,response,resultEmp,leavePeriod,leaveType);
						//save to database
						if(lid==null)
							leaveManager.createLeave(saveLeave);
						else{
							saveLeave.setLeaveId(lid);
							saveLeave.setStatus("Updated");
							leaveManager.updateLeave(saveLeave);
						}
						request.setAttribute("errorMessage", "Leave Application Process is successful!");
					}
					else{
						System.out.println("Your medical leave is not left");
						request.setAttribute("errorMessage", "Your medical leave is not left");
					}
					rs = request.getRequestDispatcher("ApplyLeaveForm.jsp");
					rs.forward(request, response);
				}
				//compensation leave
				else if(leaveType==3){
					ApplyLeaveFormBean lbean = new ApplyLeaveFormBean();
					lbean.setFromDate(fromDate);
					lbean.setToDate(toDate);
					lbean.setLeaveType(leaveType);
					lbean.setLeaveReason(request.getParameter("remark"));
					//lbean.setLeaveId(lid);
					
					session.setAttribute("ApplyFormBean", lbean);
					
					rs = request.getRequestDispatcher("Compensation.jsp");
					rs.forward(request, response);
				}
				session.setAttribute("leaveid", null);
		}//end of date validation
	}
	
	private Leave prepareLeaveObject(HttpServletRequest request, HttpServletResponse response, Employee resultEmp,int noOfLeaveDays,int leavetype){
		//get today date
		DateUtility dutil = new DateUtility();
		Date today = dutil.getDate();	
		
		Leave saveLeave = new Leave();
		saveLeave.setEmployeeId(resultEmp.getEmployeeId());//login user		
		saveLeave.setLeaveTypeId(leavetype);//form
		saveLeave.setRemainingLeaves(noOfLeaveDays);//need to calculate
		saveLeave.setLeaveReason(request.getParameter("remark"));//form data
		saveLeave.setStatus("Applied");//fixed 
		saveLeave.setRemarks(null);//form
		saveLeave.setLeaveStartDate(dutil.ConvertStringToDate(request.getParameter("fromDate")));
		saveLeave.setLeaveEndDate(dutil.ConvertStringToDate(request.getParameter("toDate")));
		saveLeave.setCreatedBy(resultEmp.getUsername());//login user
		saveLeave.setCreatedOn(today);//today date
		saveLeave.setModifiedBy(resultEmp.getUsername());//login user
		saveLeave.setModifiedOn(today);
		
		return saveLeave;
	}
}
